package com.blueocean_health.care.management.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.blueocean_health.care.management.common.base.string.StringUtils;
import com.blueocean_health.care.management.domain.base.RolePower;
import com.blueocean_health.care.management.domain.base.SysResult;
import com.blueocean_health.care.management.domain.base.Team;
import com.blueocean_health.care.management.domain.base.UserAccount;
import com.blueocean_health.care.management.domain.base.UserToken;
import com.blueocean_health.care.management.domain.dto.UserDto;
import com.blueocean_health.care.management.domain.vo.ModuleVo;
import com.blueocean_health.care.management.domain.vo.UserAccountVo;
import com.blueocean_health.care.management.domain.vo.UserVo;
import com.blueocean_health.care.management.mapper.RolePowerMapper;
import com.blueocean_health.care.management.mapper.TeamMapper;
import com.blueocean_health.care.management.mapper.UserAccountMapper;
import com.blueocean_health.care.management.mapper.UserTeamMapper;
import com.blueocean_health.care.management.mapper.UserTokenMapper;
import com.blueocean_health.care.management.service.LoginService;
import com.blueocean_health.care.management.service.PowerService;

@Service
public class LoginServiceImpl implements LoginService {
	@Autowired
	private UserTokenMapper userTokenMapper;
	@Autowired
	private UserAccountMapper userDao;
	@Autowired
	private UserTeamMapper userTeamMapper;
	@Autowired
	private PowerService powerService;
	@Autowired
	private TeamMapper teamMapper;
	@Autowired
	private RolePowerMapper rolePowerMapper;

	@Value("${service.address}")
	private String SERVICEADDRESS;

	/**
	 * 登录
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public SysResult login(UserAccount userAccount) {
		String password = userAccount.getPassword();
		// 加密
		userAccount.setPassword(DigestUtils.md5Hex(password));
		UserAccount currentUserInfo = userDao.getCurrentUserInfo(userAccount);
		if (currentUserInfo == null) {
			return SysResult.error("用户名或密码不正确");
		}
		if (currentUserInfo.getIsActive() != 1) {
			return SysResult.error("该用户被删除，无法登录");
		}
		if (currentUserInfo.getEnableStatus() != 1) {
			return SysResult.error("该用户被禁用，无法登录");
		}

		// 获得登录名对应的所有组织/项目集合
		Map<String, Object> paramsMap = new HashMap<>();
		paramsMap.put("userId", currentUserInfo.getUserId());
		paramsMap.put("type", 1);
		List<Map<String, String>> orgList = userTeamMapper.findOrgsAndProjectsByUserId(paramsMap);
		orgList = filterNotRole(orgList);

		paramsMap.put("type", 2);
		List<Map<String, String>> projectList = userTeamMapper.findOrgsAndProjectsByUserId(paramsMap);
		projectList = filterNotRole(projectList);

		// 保存token信息
		UserToken userToken = saveUserToken(currentUserInfo.getUserId(), "");
		// 返回数据
		UserDto userDto = new UserDto();
		userDto.setUserId(currentUserInfo.getUserId());
		userDto.setUserName(currentUserInfo.getUserName());
		userDto.setUserRealName(currentUserInfo.getUserRealName());
		userDto.setToken(userToken.getToken());
		userDto.setAvatar("defaultUser.jpg");
		userDto.setAvatar(SERVICEADDRESS + "defaultUser.jpg");
		// userDto.setTeamLogo(SERVICEADDRESS+"hospitalLogo.png");

		if (!StringUtils.isEmpty(orgList) && orgList.size() > 0) {
			if (!StringUtils.isEmpty(orgList.get(0))) {
				userDto.setOrgList(orgList);
			}
		}
		if (!StringUtils.isEmpty(projectList) && projectList.size() > 0) {
			if (!StringUtils.isEmpty(projectList.get(0))) {
				userDto.setProjectList(projectList);
			}
		}

		if ((StringUtils.isEmpty(orgList) || orgList.size() <= 0)
				&& (StringUtils.isEmpty(projectList) || projectList.size() <= 0)) {
			return SysResult.error("该用户不具备任何角色，无法登录");
		}

		return SysResult.ok(userDto);
	}

	/**
	 * 过滤没有配置给用户配置角色的组织/项目 @Title: filterNotRole @param orgList @return
	 * List<Map<String,String>> @version V1.0 @throws
	 */
	private List<Map<String, String>> filterNotRole(List<Map<String, String>> list) {
		if (StringUtils.isEmpty(list)) {
			list = new ArrayList<>();
		} else {
			list = list.stream().filter(map -> {
				String roleIds = map.get("roleIds");
				if (StringUtils.isEmpty(roleIds)) {
					return false;
				} else {
					List<String> roleIdList = new ArrayList<String>(Arrays.asList(roleIds.split(",")));
					roleIdList = roleIdList.stream().filter(id -> {
						if (!StringUtils.isEmpty(id)) {
							List<RolePower> rolePowers = rolePowerMapper.selectByRoleId(Integer.parseInt(id));
							if (StringUtils.isEmpty(rolePowers) || rolePowers.size() <= 0) {
								return false;
							}
							if (!StringUtils.isEmpty(rolePowers) && rolePowers.size() <= 1) {
								if (StringUtils.isEmpty(rolePowers.get(0))) {
									return false;
								}
							}
							return true;
						}
						return false;
					}).collect(Collectors.toList());

					if (StringUtils.isEmpty(roleIdList) || roleIdList.size() <= 0) {
						return false;
					} else {
						return true;
					}
				}
			}).collect(Collectors.toList());
		}
		return list;
	}

	/**
	 * 保存token信息
	 * 
	 * @param userId
	 * @param roleList
	 */
	private UserToken saveUserToken(Integer userId, String teamId) {
		UserToken userToken = new UserToken();
		userToken.setUserId(userId + "");
		userToken.setTeamId(teamId + "");
		userToken.setToken(UUID.randomUUID().toString());
		userToken.setIsActive(1);
		userToken.setIsPhone(0);
		userToken.setCreateTime(new Date());
		int count = userTokenMapper.insert(userToken);
		if (count <= 0) {
			return null;
		}
		return userToken;
	}

	/**
	 * 登录后多身份选择
	 */
	@Override
	public SysResult selectIdentity(Map<String, String> paramsMap) {
		// 将选择的组织/项目保存到对应token中
		int count = userTokenMapper.updateTokenTeamIdByToken(paramsMap);
		if (count <= 0) {
			return SysResult.error("更新token失败");
		}
		UserToken token = userTokenMapper.getTokenByToken(paramsMap.get("token"));
		// 权限列表
		List<String> permissionList = new ArrayList<>();
		// 根据userId和teamId查找权限列表
		permissionList = powerService.getUserPermissionsNew(token.getUserId(), token.getTeamId());
		if (StringUtils.isEmpty(permissionList) || permissionList.size() <= 0) {
			return SysResult.error("当前用户不具备相应权限或所属组织/项目无相应权限");
		}
		if (!StringUtils.isEmpty(permissionList) && permissionList.size() > 0) {
			if (StringUtils.isEmpty(permissionList.get(0))) {
				return SysResult.error("当前用户不具备相应权限或所属组织/项目无相应权限");
			}
		}

		Team team = teamMapper.findOrgById(Integer.parseInt(paramsMap.get("teamId")));
		Map<String, Object> data = new HashMap<>();
		data.put("permissions", permissionList);
		data.put("hospitalLogo", SERVICEADDRESS + "hospitalLogo.png");
		if (!StringUtils.isEmpty(team)) {
			data.put("hospitalName", team.getTeamName());
		}

		return SysResult.ok(data);
	}

	/**
	 * 通过token 查询用户信息
	 */
	@Override
	public UserVo getUserInfoByToken(String token) {
		UserToken userToken = userTokenMapper.getTokenByToken(token);
		if (userToken == null) {
			return null;
		}
		String userId = userToken.getUserId();
		UserAccount user = new UserAccount();
		user.setUserId(Integer.parseInt(userId));
		// 查询用户详情
		UserAccountVo userAccountVo = userDao.query(userId);

		UserVo userVo = new UserVo();
		userVo.setToken(token);
		userVo.setUserId(userAccountVo.getUserId());
		userVo.setUserName(userAccountVo.getUserName());
		userVo.setUserRealName(userAccountVo.getUserRealName());
		if (StringUtils.isEmpty(userAccountVo.getEnableStatus())) {
			userVo.setEnableStatus(Integer.parseInt(userAccountVo.getEnableStatus()));
		}
		if (!StringUtils.isEmpty(userAccountVo.getUserSource())) {
			userVo.setUserSource(Integer.parseInt(userAccountVo.getUserSource()));
		}
		// 用户真实选择的组织
		userVo.setTeamId(userToken.getTeamId());
		return userVo;
	}
}
